#ifndef _MSFS_H_
#define _MSFS_H_

#define BUF_SIZE 1024

/* sizeof(short) is supposed to get 2 */

struct dir_entry {
    char            fnm[8];         /* file name, no room for '\0' */
    char            ext[3];         /* file extention */
    char            atb;            /* attribute */
    char            span1[2];       /* reserved in FAT12 */
    char            ctime[2];       /* time of creation */
    char            cdate[2];       /* date of creation */
    char            adate[2];       /* last access date */
    char            span2[2];       /* reserved in FAT12 */
    char            mtime[2];       /* time of last modification */
    char            mdate[2];       /* date of last modification */
    unsigned short  scn;            /* start cluster number */
    unsigned int    size;           /* file size in bytes */
    unsigned int    bof;            /* byte offset of the entry */
};
#define DIR_ENTRY_SIZE  32

struct date {
    unsigned int year;
    unsigned int month;
    unsigned int day;
};

struct time {
    unsigned int hour;
    unsigned int miniute;
    unsigned int second;
};

/*
 * no cyclic shift
 * s is supposed to be an array of char of size 2
 */
/* extract date from char s[2] */
#define EXTRACT_YEAR(d, s) \
    do { \
        (d) = 0; \
        (d) |= ((s)[1] >> 1); \
        (d) += 1980; \
    } while (0)
#define EXTRACT_MONTH(d, s) \
    do { \
        (d) = 0; \
        (d) |= (((s)[1] & 0x01) << 4); \
        (d) |= ((s)[0] >> 5); \
    } while (0)
#define EXTRACT_DAY(d, s) \
    do { \
        (d) = 0; \
        (d) |= ((s)[0] & 0x0f); \
    } while (0)
/* extract time from char s[2] */
#define EXTRACT_HOUR(d, s) \
    do { \
        (d) = 0; \
        (d) |= (((s)[1] & 0xf8) >> 3); \
    } while (0)
#define EXTRACT_MINIUTE(d, s) \
    do { \
        (d) = 0; \
        (d) |= (((s)[1] & 0x07) << 3); \
        (d) |= (((s)[0] & 0xe0) >> 5); \
    } while (0)
#define EXTRACT_SEC(d, s) \
    do { \
        (d) = 0; \
        (d) |= ((s)[0] & 0x1F); \
        (d) <<= 1; \
    } while (0)

/* definitions of the first byte of the filename */
#define FBFN_UNUSED         0x00    /* representing a terminating entry */
#define FBFN_DELETED        0xe5    /* deleted, subdirectoy, or volumn label */
#define FBFN_DOT            0x2e    /* current (.) or parent directory (..) */
#define FBFN_NEXT_VALID     0x41

#define DOT_CUR_DIR     ".\x20\x20\x20\x20\x20\x20\x20"
#define DOT_PAR_DIR     "..\x20\x20\x20\x20\x20\x20"

/* definitions of the directory entry attributes */
#define DEA_ARV             0x20    /* archive */
#define DEA_DIR             0x10    /* directory */
#define DEA_VLB             0x08    /* volumn label */
#define DEA_SYS             0x04    /* system */
#define DEA_HID             0x02    /* hidden */
#define DEA_RDO             0x01    /* read only */

enum command_type {
    CMD_LOAD, CMD_LS, CMD_CD, CMD_RM, CMD_EXIT, CMD_UNVALID,
};

/* control the output of debug message */
//#define DEBUG "debuging: "

#endif
